package org.xurui.bsj.protocol.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
public class BinaryUtils {

    public static String CMD_AT = "@";
    public static String CMD_EXCLAMATION = "!";
    public static String CMD_NUMBER = "#";
    public static String CMD_DOLLAR = "$";

    /**
     * 十六进制字符串转二进制字符串
     * @param hexStr 十六进制字符串
     * @return 二进制字符串
     */
    public static String hexToBin(String hexStr) {
        String hexToBinStr = "";
        try {
            hexToBinStr = Long.toBinaryString(Long.valueOf(hexStr, 16));
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }
        return hexToBinStr;
    }

    /**
     * 设备状态，共四字节，用 ASCII 字符表示 16 进制值
     * 位序 第一字节 第二字节 第三字节 第四字节
     * 0 1 保留 1 保留 1 保留 0 在围栏1内
     * 1 0 M2 模式 0 GPS 开 0 静止 0 充电
     * 2 1 保留 1 保留 1 保留 0 考勤开关
     * 3 1 保留 1 保留 1 保留 0 围栏 1 设置情况
     * 4 1 保留 1 保留 1 保留 0 免打扰中
     * 5 0 M1 模式 0 M3 模式 0 已定位 0 WiFi定时扫描
     * 6 1 保留 1 保留 1 保留 0 免打扰开关
     * 7 1 保留 1 保留 1 保留 0 免打扰设置情况
     * @param binaryStr
     * @param byteIndex
     * @param bitIndex
     * @return
     */
    public static Integer parseTrackerStatus(String binaryStr,Integer byteIndex,Integer bitIndex){
        return Integer.parseInt(binaryStr.charAt((byteIndex-1)*8+(7-bitIndex))+"");
    }

    /**
     * 判断是否含有特殊字符
     *
     * @param str
     * @return true为包含，false为不包含
     */
    public static boolean isSpecialChar(String str) {
        String regEx = "[*,#]";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(str);
        return m.find();
    }

    /**
     * 限制运营商 MNC 判断
     * @param type
     * @param target
     * @return
     */
    public static boolean isMNC(String type,String target) {
        String ydArr = "00 02 04 07 08 13";//1 移动
        String ltArr = "01 06 09 10";//2 联通
        String dxArr = "03 11 12";//3 电信
        String ydltArr = "00 02 04 07 08 13 01 06 09 10";//4 仅移动和联通
        String bxzArr = "00 02 04 07 08 13 01 06 09 10 03 11 12";//0 不限制
        boolean regexp=false;
        if(type.equals("1")){
            regexp = ydArr.contains(target);
        }else if(type.equals("2")){
            regexp = ltArr.contains(target);
        }else if(type.equals("3")){
            regexp = dxArr.contains(target);
        }else if(type.equals("4")){
            regexp = ydltArr.contains(target);
        }else if(type.equals("0")){
            regexp = bxzArr.contains(target);
        }
        return regexp;
    }

    public static Map getGps(String gpsName){
        Map mp=new HashMap();
        //定位状态 =“0”：表示定位成功； =“1”：表示定位失败； =“2”：表示 GPS 未打开，或 GPS 位置暂不用等其它情况
        String gpsStatus=gpsName.substring(0,1);
        //经度标识 =“E”：表示东经（+） = “W”：表示西经
        String lonBs=gpsName.substring(1,2);
        String longitude="";
        String latBs="";
        String latitude="";
        String timeBs="";
        String time="";
        if("0.0".equals(gpsName.substring(2,5))){
            //经度 单位 ：度格式为bbb.bbbbbb,后六位为小数
             longitude=gpsName.substring(2,10);
            //纬度标识 =“N”：表示北纬（+） = “S”： 表示南纬
             latBs=gpsName.substring(10,11);
            //纬度 单位：度格式为bb.bbbbbb, 后六位为小数
             latitude=gpsName.substring(11,19);
            //时间标识 =“T”:表示时间
             timeBs=gpsName.substring(19,20);
            //年 YYYY
            String year=gpsName.substring(20,24);
            //月 MM
            String month=gpsName.substring(24,26);
            //日 DD
            String day=gpsName.substring(26,28);
            //时 HH
            String hour=gpsName.substring(28,30);
            //分 MM
            String minute=gpsName.substring(30,32);
            //秒 SS
            String second=gpsName.substring(32,34);
            time=year+"-"+month+"-"+day+" "+hour+":"+minute+":"+second;
        }else{
            //经度 单位 ：度格式为bbb.bbbbbb,后六位为小数
             longitude=gpsName.substring(2,12);
            //纬度标识 =“N”：表示北纬（+） = “S”： 表示南纬
             latBs=gpsName.substring(12,13);
            //纬度 单位：度格式为bb.bbbbbb, 后六位为小数
             latitude=gpsName.substring(13,22);
            //时间标识 =“T”:表示时间
             timeBs=gpsName.substring(22,23);
            //年 YYYY
            String year=gpsName.substring(23,27);
            //月 MM
            String month=gpsName.substring(27,29);
            //日 DD
            String day=gpsName.substring(29,31);
            //时 HH
            String hour=gpsName.substring(31,33);
            //分 MM
            String minute=gpsName.substring(33,35);
            //秒 SS
            String second=gpsName.substring(35,37);
            time=year+"-"+month+"-"+day+" "+hour+":"+minute+":"+second;
        }




        mp.put("gpsStatus",gpsStatus);
        mp.put("lonBs",lonBs);
        mp.put("longitude",longitude);
        mp.put("latBs",latBs);
        mp.put("latitude",latitude);
        mp.put("timeBs",timeBs);
        mp.put("time",time);



        return mp;
    }

    public static String getDateFormat(){
        SimpleDateFormat sdf = new SimpleDateFormat("ddMMyy");
        String time=sdf.format(new Date());
        return time;
    }

    /**
     * 经度、纬度值，
     * @param lonlat
     * @param type lon lat
     * @return
     */
    public static String getWgs84LonLat(String lonlat,String type){
        if(!StringUtils.isEmpty(lonlat)){
            try {
                if("lon".equals(type)){
                    int lo=Integer.parseInt(lonlat.substring(0,3));
                    double ln=Double.parseDouble(lonlat.substring(3,lonlat.length()));
                    lonlat=String.format("%.6f",lo+ln/60);
                }else if("lat".equals(type)){
                    int la=Integer.parseInt(lonlat.substring(0,2));
                    double lt=Double.parseDouble(lonlat.substring(2,lonlat.length()));
                    lonlat=String.format("%.6f",la+lt/60);
                }
            }catch (Exception e){
                log.error("解析经纬度异常！",e);
            }

        }

        return lonlat;
    }

    public static void main(String[] args){
        String n="11341.794";
        String t="3442.6990";
        String lon=getWgs84LonLat(n,"lon");
        System.out.println(lon);
        String lat=getWgs84LonLat(t,"lat");
        System.out.println(lat);
//        String s = "FFFFDFFF";
//        String binaryStr = hexToBin(s);
//        System.out.println(binaryStr);
//        System.out.println(parseTrackerStatus(binaryStr,3,5));
//        parseDay(7,1);
//        System.out.println(2<<-1);
      /* List<Integer> tempList = new ArrayList();
       parseDayIndex(126,tempList);
        System.out.println(tempList);*/
    }

    public static void parseDayIndex(Integer sum,List<Integer> days) {
        if(sum==0){
            days.add(0);
            return;
        }
        if(sum==127){
            days.add(127);
            return;
        }
        int tempNum = 2;
        for(int i=-1;i<7;i++){
            int result = 0;
            int day = 0;
            if(i==-1){
                result = 1;
                day = 1;
            }else{
                result = tempNum<<i;
                day = i+1;
            }
            if(result==sum){
                days.add(day);
                return;
            }else if(result>sum){
                int checked = result>>1;
                days.add(day);
                parseDayIndex(sum-checked,days);
                return;
            }
        }
    }


    /**
     * 字符串转换成为16进制(无需Unicode编码)
     * @param str
     * @return
     */
    public static String str2HexStr(String str) {
        char[] chars = "0123456789ABCDEF".toCharArray();
        StringBuilder sb = new StringBuilder("");
        byte[] bs = str.getBytes();
        int bit;
        for (int i = 0; i < bs.length; i++) {
            bit = (bs[i] & 0x0f0) >> 4;
            sb.append(chars[bit]);
            bit = bs[i] & 0x0f;
            sb.append(chars[bit]);
            // sb.append(' ');
        }
        return sb.toString().trim();
    }

    /**
     * 16进制直接转换成为字符串(无需Unicode解码)
     * @param hexStr
     * @return
     */
    public static String hexStr2Str(String hexStr) {
        String str = "0123456789ABCDEF";
        char[] hexs = hexStr.toCharArray();
        byte[] bytes = new byte[hexStr.length() / 2];
        int n;
        for (int i = 0; i < bytes.length; i++) {
            n = str.indexOf(hexs[2 * i]) * 16;
            n += str.indexOf(hexs[2 * i + 1]);
            bytes[i] = (byte) (n & 0xff);
        }
        return new String(bytes);
    }

    /**
     * GCJ-02 转换 WGS84
     * @param hx
     * @return
     */
    public static LonLat gcj02towgs84(LonLat hx){
        //π
        double pi = 3.1415926535897932384626;
        double a = 6378245.0;// 长半轴
        double ee = 0.00669342162296594323; // 扁率

        if (OutOfChina(hx)){
            return hx;
        }

        double dlat = transformlat(hx.lng - 105.0, hx.lat - 35.0);

        double dlng = transformlng(hx.lng - 105.0, hx.lat - 35.0);

        double radlat = hx.lat / 180.0 * pi;

        double magic = Math.sin(radlat);

        magic = 1 - ee * magic * magic;

        double sqrtmagic = Math.sqrt(magic);

        dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi);

        dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * pi);

        LonLat wgs84 = new LonLat();

        double mglat = hx.lat + dlat;

        double mglng = hx.lng + dlng;

        wgs84.lat = hx.lat * 2 -mglat;

        wgs84.lng = hx.lng *2-mglng;

        return wgs84;

    }

    public static String getLonLatToWgs84(String lonlat,String type){
        if(!StringUtils.isEmpty(lonlat)){
            try {
                if("lon".equals(type)){
                    String lo=lonlat.substring(0,3);
                    String ln=String.format("%.4f",Double.parseDouble(lonlat.substring(3,lonlat.length()))*60);
                    lonlat=lo+ln;
                }else if("lat".equals(type)){
                    String la=lonlat.substring(0,2);
                    String lt=String.format("%.4f",Double.parseDouble(lonlat.substring(2,lonlat.length()))*60);
                    lonlat=la+lt;
                }
            }catch (Exception e){
                log.error("解析经纬度异常！",e);
            }

        }

        return lonlat;
    }

    /*辅助函数*/
    //判断是否在国内
    private static Boolean OutOfChina(LonLat wgs84){

        if (wgs84.lng < 72.004 || wgs84.lng > 137.8347){
            return true;
        }

        if (wgs84.lat < 0.8293 || wgs84.lat > 55.8271){
            return true;
        }

        return false;
    }

    /*辅助函数*/
    //转换lat
    private static double transformlat(double lng, double lat){
        double pi = 3.1415926535897932384626;

        double ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));

        ret += (20.0 * Math.sin(6.0 * lng * pi) + 20.0 * Math.sin(2.0 * lng * pi)) * 2.0 / 3.0;

        ret += (20.0 * Math.sin(lat * pi) + 40.0 * Math.sin(lat / 3.0 * pi)) * 2.0 / 3.0;

        ret += (160.0 * Math.sin(lat / 12.0 * pi) + 320 * Math.sin(lat * pi / 30.0)) * 2.0 / 3.0;

        return ret;

    }

    /*辅助函数*/
    //转换lng
    private static double transformlng(double lng, double lat){
        //π
        double pi = 3.1415926535897932384626;
        double ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));

        ret += (20.0 * Math.sin(6.0 * lng * pi) + 20.0 * Math.sin(2.0 * lng * pi)) * 2.0 / 3.0;

        ret += (20.0 * Math.sin(lng * pi) + 40.0 * Math.sin(lng / 3.0 * pi)) * 2.0 / 3.0;

        ret += (150.0 * Math.sin(lng / 12.0 * pi) + 300.0 * Math.sin(lng / 30.0 * pi)) * 2.0 / 3.0;

        return ret;

    }
}
